package com.aube.rvi.module;

import com.aube.rvi.AubeAgent;
import com.aube.rvi.util.Constant;
import com.aube.rvi.util.StringUtils;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author huyn
 * @version 2013-12-9 下午4:43:26
 */

public class ParamParser {

	private static HashMap<String, String> getParaMaps(HashMap<String, String> params) {
		if(!params.containsKey(Constant.APP_KEY_OSTYPE)) {
			params.put(Constant.APP_KEY_OSTYPE, Constant.OS_TYPE);
		}
		if(!params.containsKey(Constant.APP_KEY_OSVERSION)) {
			params.put(Constant.APP_KEY_OSVERSION, android.os.Build.VERSION.RELEASE);
		}
		//sdk version
//		if(!params.containsKey(Constant.APP_KEY_APIVERSION)) {
//			params.put(Constant.APP_KEY_APIVERSION, AubeAgent.SDK_VERSION);
//		}

		if(!params.containsKey(Constant.APP_KEY_NAME)) {
			params.put(Constant.APP_KEY_NAME, Constant.APP_NAME);
		}
		if(!params.containsKey(Constant.APP_KEY_DEVICEID)) {
			params.put(Constant.APP_KEY_DEVICEID, Constant.APP_DEVICEID);
		}
		if(!params.containsKey(Constant.APP_KEY_MOBILETYPE)) {
			params.put(Constant.APP_KEY_MOBILETYPE, Constant.APP_MOBILETYPE);
		}
		if(!params.containsKey(Constant.APP_KEY_IMEI)) {
			params.put(Constant.APP_KEY_IMEI, Constant.APP_IMEI);
		}
		if(!params.containsKey(Constant.APP_KEY_APPKEY)) {
			params.put(Constant.APP_KEY_APPKEY, Constant.APP_KEY);
		}

		//api version
		if(!params.containsKey(Constant.APP_KEY_APIVERSION)) {
			params.put(Constant.APP_KEY_APIVERSION, "1");
		}

		if(!params.containsKey(Constant.APP_KEY_APIVERSION)) {
			params.put(Constant.APP_KEY_APIVERSION, "1.0.0");
		}
		if(!params.containsKey("appSource")) {
			params.put("appSource", "AS01");
		}
		return params;
	}

	public static HashMap<String, String> ParserParamsAPI(HashMap<String, String> params) {
		params = getParaMaps(params);

		ArrayList<String> list = new ArrayList<String>();
		ArrayList<String> mRemoveList = new ArrayList<String>();

		for (Map.Entry<String, String> item : params.entrySet()) { 
			if(item.getValue()==null){
				mRemoveList.add(item.getKey());
			}
			list.add(item.getKey());
		}
		
		int removeCount = mRemoveList.size();
		for(int i=0;i<removeCount;i++){
			params.remove(mRemoveList.get(i));
			list.remove(mRemoveList.get(i));
		} 
		 
		Collections.sort(list);
		int listSize = list.size();
		TreeMap<String, String> treeMap = new TreeMap<String, String>();
		for(int i=0;i<listSize;i++){
			treeMap.put(list.get(i), params.get(list.get(i)));
		}
		
		String sign = "";
		try{
			sign = signRequest(treeMap, Constant.PRIVATE_KEY);
		}catch (Exception e) {
		}

		params.put("sign", sign);
		params.put("signmethod", "MD5");
		 
		return params;
	}

	/**
	 * 给请求签名。
	 *
	 * @param params 所有字符型的请求参数
	 * @param secret 签名密钥
	 * @return 签名
	 * @throws IOException
	 */
	public static String signRequest(Map<String, String> params, String secret) throws IOException {
		// 第一步：把字典按Key的字母顺序排序
		Map<String, String> sortedParams = new TreeMap<String, String>(params);

		// 第二步：把所有参数名和参数值串在一起
		StringBuilder orgin = new StringBuilder();
		for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
			orgin.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
		}
		String query = StringUtils.substringBeforeLast(orgin.toString(), "&") + secret;

		// 第三步：使用MD5加密
		MessageDigest md5 = getMd5MessageDigest();
		byte[] bytes = md5.digest(query.getBytes(Constant.CHARSET_UTF8));

		// 第四步：把二进制转化为大写的十六进制
		StringBuilder sign = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() == 1) {
				sign.append("0");
			}
			sign.append(hex.toUpperCase());
		}

		return sign.toString().toUpperCase();
	}

	private static MessageDigest getMd5MessageDigest() throws IOException {
		try {
			return MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			throw new IOException(e.getMessage());
		}
	}

}
